package org.brisling.workflow.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.HistoryService;
import org.activiti.engine.ManagementService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.brisling.base.domain.RetDomain;
import org.brisling.base.domain.inf.BaseFlowDomainInf;
import org.brisling.common.SysConfig;
import org.brisling.common.util.MapUtil;
import org.brisling.sysman.domain.JobRole;
import org.brisling.sysman.domain.UserRoles;
import org.brisling.sysman.domain.VOJobUser;
import org.brisling.sysman.queryService.QueryJobRoleService;
import org.brisling.sysman.queryService.QueryUserRoleService;
import org.brisling.workflow.cmd.JumpCmd;
import org.brisling.workflow.domain.FlowTaskConfig;
import org.brisling.workflow.domain.VOHistoric;
import org.brisling.workflow.queryService.QueryTaskconfigService;
import org.brisling.workflow.service.base.BaseWorkflowService;
import org.brisling.workflow.util.NodeUser;
import org.brisling.workflow.util.NodeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 工作流公共Service
 *
 * @author jackson wang
 */
@RestController
@RequestMapping("/flowOperator")
public class WorkflowOperatorService extends BaseWorkflowService{

    private static Logger logger = LoggerFactory.getLogger(WorkflowOperatorService.class);    
    
    @Autowired
    private ManagementService managementService;
    
    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
  	private QueryJobRoleService jobService;

    @Autowired
  	private QueryUserRoleService roleService;
    
    @Autowired
  	private QueryTaskconfigService qryTaskconfigService;
    /**
     * 启动流程业务
     * @param flowEntity 业务实体类
     * @param fullBizCode 业务代码全称
     * @param variables	 流程变量
     * @return	获取流程信息后的业务实体类     
     */
    public BaseFlowDomainInf startWorkflowByDefinitionId(String userid,String processDefinitionId,String businessKey,Map<String, Object> variables,BaseFlowDomainInf flowEntity)  {
    	
    	//判断业务流程参数
    	if((processDefinitionId==null)||(processDefinitionId.trim().length()<=0)){
    		return null;     		
    	}           	
    	
    	//判断业务代码是否为空
        if((businessKey==null)||(businessKey.trim().length()<=0)){
        	return null;        	
        }
    	
    	ProcessInstance processInstance = null;
        try {        	
            processInstance = runtimeService.startProcessInstanceById(processDefinitionId, businessKey, variables);
            String processInstanceId = processInstance.getId();
            flowEntity.setFlowInstId(processInstanceId);
            Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
//            taskService.setAssignee(task.getId(), userid);
//            taskService.saveTask(task);
            flowEntity.setFlowTaskId(task.getId());
            
            logger.debug("start process of {key={}, bkey={}, pid={},variables={}}", new Object[]{processDefinitionId, businessKey, processInstanceId,variables});
        } catch(Exception e) {
            e.printStackTrace();
        }
        
    	return flowEntity;       
    }
    
    /**
     * * 根据流程定义 processDefinitionKey 启动业务流程
     * @param processDefinitionKey
     * @param businessKey
     * @param variables
     * @param entityId
     * @return BaseFlowDomainInf 增加了流程信息的业务实体类
     */
    public BaseFlowDomainInf startWorkflowByDefinitionKey(String processDefinitionKey,String businessKey,Map<String, Object> variables,BaseFlowDomainInf flowEntity)  {
    	
    	
    	
    	//判断业务流程参数
    	if((processDefinitionKey==null)||(processDefinitionKey.trim().length()<=0)){
    		return null;     		
    	}
       
    	//判断业务对象实体是否已经保存
    	if(flowEntity.getId()==null){
    		return null;   
    	}
    	
    	//判断业务代码是否为空
        if((businessKey==null)||(businessKey.trim().length()<=0)){
        	return null;        	
        }
        
        
        

        ProcessInstance processInstance = null;
        try {        	
            processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey, variables);
            String processInstanceId = processInstance.getId();
            flowEntity.setFlowInstId(processInstanceId);
            Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
            flowEntity.setFlowTaskId(task.getId());
            logger.debug("start process of {key={}, bkey={}, pid={}, variables={}}", new Object[]{processDefinitionKey, businessKey, processInstanceId,variables});
        } catch(Exception e) {
            
        }
        return flowEntity;
    }
    
   
    
    /**
     * 将 processInstanceId 所对应业务流程移交 assignee所对应人员
     * @param processInstanceId
     * @param assignee
     * @return
     */
    public String processInstanceUserAssignee(String processInstanceId,String assigneeUserid) {    	
        
        try {
            // 用来设置流程受理人员ID，引擎会自动把用户ID保存到activiti:initiator中
//            identityService.setAuthenticatedUserId(flowEntity.getUserid().toString());        	
        	
        	Task taskInstance = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult(); 
        	
        	taskInstance.setAssignee(assigneeUserid);
        	
        	taskService.saveTask(taskInstance);
            
            logger.debug("start process of {name={},processInstanceId={}, variables={}}", new Object[]{taskInstance.getName(), taskInstance.getId(), taskInstance.getProcessVariables()});
        }catch(Exception e){
        	return "500";
        }
        return "200";
    }
    
    /**
     * 将 processInstanceId 所对应业务流程移交 assigneeGroupId 所对应组
     * @param processInstanceId
     * @param assignee
     * @return
     */
    public String processInstanceGroupAssignee(String processInstanceId,String assigneeGroupId) {    	
        
        try {
            // 用来设置流程受理人员ID，引擎会自动把用户ID保存到activiti:initiator中
//            identityService.setAuthenticatedUserId(flowEntity.getUserid().toString());        	
        	
        	Task taskInstance = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult(); 
        	
        	taskInstance.setAssignee(assigneeGroupId);
        	taskService.saveTask(taskInstance);
            
            logger.debug("start process of {name={},processInstanceId={}, variables={}}", new Object[]{taskInstance.getName(), taskInstance.getId(), taskInstance.getProcessVariables()});
        }catch(Exception e){
        	return "500";
        }
        return "200";
    }
    
    /**
     * 业务流程签收，将 processInstanceId 所对应当前流程节点签收人员设置为 claimer 
     * @param processInstanceId
     * @param claimer
     * @return	签收状态标志
     */
    public String processInstanceClaim(String processInstanceId,String claimer) {    	
        
        try {
            // 用来设置流程受理人员ID，引擎会自动把用户ID保存到activiti:initiator中
//            identityService.setAuthenticatedUserId(flowEntity.getUserid().toString());        	
        	
        	Task taskInstance = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult(); 
        	taskService.claim(taskInstance.getId(), claimer);        	
            
            logger.debug("claiming Task of {taskInstanceId={},claimer={}, TaskLocalVariables={}}", new Object[]{ taskInstance.getId(),claimer, taskInstance.getTaskLocalVariables()});
        }catch(Exception e){
        	return "500";
        }
        return "200";
    }

    /**
     * 查询待办任务id
     *
     * @param userId 用户ID
     * @return
     */
    
    public List<Long> findTodoTaskIds(String userId, int[] pageParams) {
        List<Long> results = new ArrayList<Long>();

        // 根据当前人的ID查询
        TaskQuery taskQuery = taskService.createTaskQuery().taskCandidateOrAssigned(userId);
        List<Task> tasks = taskQuery.list();

        // 根据流程的业务ID查询实体并关联
        for (Task task : tasks) {
            String processInstanceId = task.getProcessInstanceId();
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).active().singleResult();
            String businessKey = processInstance.getBusinessKey();
            if (businessKey == null) {
                continue;
            }
            
            results.add(new Long(businessKey));
            
        }
        
        return results;
    }

    /**
     * 获取特定业务代码的流程信息集合
     * @param bizcode	业务流程编码
     * @param firstRow	分页参数起始值
     * @param maxRow	分页参数结束值
     * @return	Map<String,Task>
     */
    
    public Map<String,Task> findRunningProcessInstaceIds(String bizcode, int firstRow,int maxRow) {
    	Map<String,Task> results = new HashMap<String,Task>();
        
        if(firstRow<0)
        	firstRow = 0;
        if(maxRow<=0)
        	maxRow = 10;
//        List<ProcessInstance> procs = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(bizcode).listPage(firstRow, maxRow);
        List<Task> groupTasks = taskService.createTaskQuery().processInstanceBusinessKey(bizcode).listPage(firstRow,maxRow);
        for(Task task :groupTasks){
        	results.put(task.getProcessInstanceId(),task);
        }
        
        return results;
    }
    
   /**
    * 获取指定任务编码的流程业务信息
    * @param instId	流程实例编码
    * @return
    */
    
    public Task findRunningProcessInstace(String instId) {
    	
    	Task task = null;
    	if((instId!=null) && (instId.trim().length()>0))        
    		task = taskService.createTaskQuery().processInstanceId(instId).singleResult();
    	
        return task;
    }
    
    /**
     * 获取指定任务编码的流程执行信息
     * @param procInstId	流程实例编码
     * @return 流程执行节点信息
     */
    @RequestMapping("/flowHistorics.action")
     public List<VOHistoric> findHistoricProcessInfo(@RequestParam(value="flowInstId",required=false)String procInstId) {
     	
    	List<VOHistoric> voList= new ArrayList<VOHistoric>(); 
     	if((procInstId!=null) && (procInstId.trim().length()>0)) {      
     		List<HistoricTaskInstance> historic =  historyService.createHistoricTaskInstanceQuery().processInstanceId(procInstId).list();
     		
     		VOHistoric vo = null;
     		for(int i=0;i<historic.size();i++){
     			vo = new VOHistoric();
     			BeanUtils.copyProperties(historic.get(i), vo, VOHistoric.class);
     			voList.add(vo);
     		}
     	}
     	
        return voList;
     }
    
    
    
    /**
     * 获取指定任务编码的流程业务信息
     * @param instId	流程实例编码
     * @param signInfo  签收意见
     * @return
     */
     @RequestMapping("/flowSign.action")
     public String saveSignTask(String userid,String instId,String taskId,String signInfo) {
    	 
    	 if((userid!=null) && (userid.trim().length()>0))
    		 userid=userid.trim();
    	 else
    		 return "userid 不能为空";
    	 
    	 if((instId!=null)&&(instId.trim().length()>0))
    		 instId=instId.trim();
    	 else
    		 return "流程实例id 不能为空"; 
    	 
    	 if((taskId!=null)&&(taskId.trim().length()>0))
    		 taskId=taskId.trim();
    	 else
    		 return "任务id 不能为空";    	 
    	 
    	 Task task = taskService.createTaskQuery().processInstanceId(instId).singleResult();     		
    	 String assigneeId = task.getAssignee();
    	 
    	 //当前任务节点未变化
    	 if(task.getId().compareTo(taskId)==0){
    		 //任务尚未签收
	    	 if((assigneeId==null)||(assigneeId.trim().length()<=0)){
//	    		 taskService.claim(task.getId(), userid);
	    		 task.setAssignee(userid);
	    	 }else{
	    		 if(userid.compareTo(assigneeId.trim())!=0){
	        		 return "业务已被他人签收，请刷新页面";
	        	 }
	    	 }    
	     		
	     	 task.setDescription(signInfo);
	     	 taskService.saveTask(task);
	     	 
	         return "200";
     	}else{
    		 return "任务已被他人执行，请刷新页面";
    	 }
     }

    /**
     * 
     * 读取已结束的流程
     *     
     * @param bizcode	流程定义业务编码
     * @param pageParams	分页参数
     * @return
     */
    
    public Map<String,HistoricProcessInstance> findFinishedProcessInstaces(String bizcode, Integer[] pageParams) {
    	Map<String,HistoricProcessInstance> results = new HashMap<String,HistoricProcessInstance>();
        HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(bizcode).finished().orderByProcessInstanceEndTime().desc();
        List<HistoricProcessInstance> list = query.listPage(pageParams[0], pageParams[1]);

        // 关联业务实体
        for (HistoricProcessInstance historicProcessInstance : list) {
            String procid = historicProcessInstance.getId();
            
            results.put(procid,historicProcessInstance);
        }
        
        return results;
    }

    /**
     * 查询流程定义对象
     *
     * @param processDefinitionId 流程定义ID
     * @return
     */
    public ProcessDefinition getProcessDefinition(String processDefinitionId) {
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
        return processDefinition;
    }
    
    @SuppressWarnings("unused")
	public List<String> getTransitionList(String processdefinitionId){
    	
    	List<Execution> executions = runtimeService.createExecutionQuery().processInstanceId(processdefinitionId).list() ;
    	Task task = null;
    	
    	executions.get(0).getActivityId();
    	
    	TransitionImpl impl = null;
    	
    	return null;
    	
    }
    
    /** 
     * 根据实例编号查找下一个任务节点 
     * @param String procInstId ：实例编号 
     * @return 
     */  
    public List<ActivityImpl> getTaskDefinition(String procInstId){  
        //流程标示  
        String processDefinitionId = historyService.createHistoricProcessInstanceQuery().processInstanceId(procInstId).singleResult().getProcessDefinitionId();  
          
        ProcessDefinitionEntity def = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(processDefinitionId);  
                
        //获得当前任务的所有节点  
        List<ActivityImpl> activitiList = def.getActivities();  
       
        return activitiList;  
    }  
    
    
    
   /**
    * 流程节点执行
    * @param procInstId	流程实例id
    * @param signInfo	签收意见
    * @param userid		用户代码
    * @return
    */
    public String saveTaskComplete(String userid,String procInstId,String flowTaskId,String signInfo,Map<String,Object> variables){
    	
    	//判断流程实例id和流程节点id不为空
    	if( ((procInstId!=null) && (procInstId.trim().length()>0))   
    			&& 
    		((flowTaskId!=null) && (flowTaskId.trim().length()>0))    ){
    		
    		Task task = taskService.createTaskQuery().processInstanceId(procInstId).singleResult();
    		
    		//判断当前实例节点有无变化
    		if(task.getId().compareTo(flowTaskId)==0){
	    		if((signInfo!=null) &&(signInfo.trim().length()>0)){
	        		if((userid!=null) &&(userid.trim().length()>0)){
	        			this.saveSignTask(userid,procInstId, flowTaskId, signInfo);    			
	        		}
	        	}
	        	
	    		if(variables!=null)
	    			taskService.complete(task.getId(),variables);
	    		else
	    			taskService.complete(task.getId());
	        	
	        	return "200";
    		}
    	}
    	
    	return "500";
    	
    	
    }
    
    /**
     * 流程节点执行并对下一节点人员根据过滤条件进行授权
     * @param procInstId	流程实例id
     * @param signInfo	签收意见
     * @param userid		用户代码
     * @return
     */
     public String completeTaskAndCandidate(String userid,BaseFlowDomainInf domain,String signInfo){
     	
     	return this.completeTaskAndCandidate(userid, domain, signInfo, null);
     }
     
     /**
      * 流程节点执行并对下一节点人员根据过滤条件进行授权
      * @param procInstId	流程实例id
      * @param signInfo	签收意见
      * @param userid		用户代码
      * @return
      */
      public String completeTaskAndCandidate(String userid,BaseFlowDomainInf domain,String signInfo,Map<String,Object> variables){
      	
      	//判断流程实例id和流程节点id不为空
     	if(domain!=null){
     		String procInstId = domain.getFlowInstId();
     		String flowTaskId =domain.getFlowTaskId();
     		if(((procInstId!=null) && (procInstId.trim().length()>0))   
      			&&((flowTaskId!=null) && (flowTaskId.trim().length()>0))    ){       		
      		
	      		Map<String,Object> _variable = null;
	      		
	      		//获取流程变量定义
	      		if(variables==null || variables.size()<=0){
	      			FlowTaskConfig ftc = qryTaskconfigService.getByProcDefinitionIdAndActivityId(domain.getFlowid(), domain.getTask_def_key());
	      			_variable = NodeUtil.getNodeVariable(domain, ftc);
	      		}       

	      		return this.saveTaskComplete(userid, procInstId, flowTaskId, signInfo,_variable);	
  	            		
      	    }
     	}
      	return "500";     	
      }
     
     /**
      * 流程节点回退
      * @param domain	流程实体
      * @param backNodeKey	回退节点名称
      * @param userid		操作人员
      * @param signInfo		签收信息
      * @return
      */
     public RetDomain saveSendBackBackup(String userid,BaseFlowDomainInf domain,String backNodeKey,String signInfo) {

    		
    		RetDomain retDomain = new RetDomain();
    		
    		if(domain==null){
    			retDomain.setErrorMsg("流程实例不能为空");
    			return retDomain;
    		}
    		
    		if(domain.getFlowTaskId()==null || domain.getFlowInstId()==null){
    			retDomain.setErrorMsg("流程id不能为空");
    			return retDomain;
    		}
    		
    		//流程变量
    		Map<String, Object> variables;

    		// 取得当前任务
    		Task currTask  = taskService.createTaskQuery().taskId(domain.getFlowTaskId()).singleResult();    		
    		
    		
    		// 取得流程实例

    		ProcessInstance instance = runtimeService
    				.createProcessInstanceQuery()
    				.processInstanceId(currTask.getProcessInstanceId())
    				.singleResult();

    		if (instance == null) {
    			retDomain.setErrorMsg("流程实例不存在");
    			return retDomain;
    		}

    		variables=instance.getProcessVariables();

    		// 取得流程定义    		
    		ProcessDefinitionEntity definition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
    					.getDeployedProcessDefinition(currTask.getProcessDefinitionId());

    		if (definition == null) {
    			retDomain.setErrorMsg("流程定义不存在");
    			return retDomain;
    		}

    		// 取得当前节点的后续环节定义
    		ActivityImpl currActivity = ((ProcessDefinitionImpl) definition)
    				.findActivity(currTask.getTaskDefinitionKey());

    		List<PvmTransition> nextTransitionList = currActivity.getOutgoingTransitions();
    		
    		
    		
    		
    		//清除原有方向
			currActivity.getOutgoingTransitions().removeAll(nextTransitionList);
			
			
			//新节点定义
			TransitionImpl newTransition = currActivity.createOutgoingTransition();
			ActivityImpl nextActivityImpl = null;
			
			String _back_node_key = null;
			//查找回退节点
			if(backNodeKey!=null && backNodeKey.trim().length()>0){
				//指定节点回退
				_back_node_key = backNodeKey.trim();
				
				
			}else{
				//获取前一节点
	    		List<PvmTransition> inTransitionList = currActivity.getIncomingTransitions();
				if(inTransitionList!=null && inTransitionList.size()>0){
					_back_node_key = inTransitionList.get(0).getSource().getId();
					
				}else{
					
					retDomain.setErrorMsg("回退节点不存在");
	    			return retDomain;
				}
			}
			
			String assigneeId = null;
			if(_back_node_key!=null){
				nextActivityImpl = ((ProcessDefinitionImpl) definition)						
					.findActivity(_back_node_key);
				
				//查找回退节点执行人员
				List<HistoricTaskInstance> priorTasks =historyService.createHistoricTaskInstanceQuery()
					.processInstanceId(currTask.getProcessInstanceId())
					.taskDefinitionKey(_back_node_key)
					.orderByHistoricTaskInstanceEndTime()
					.desc()
					.list();
				if(priorTasks!=null && priorTasks.size()>0){
					assigneeId = priorTasks.get(0).getAssignee();
				}else{
					retDomain.setErrorMsg("回退节点执行人员不存在");
	    			return retDomain;
				}
			}else{
				retDomain.setErrorMsg("回退节点不存在");
    			return retDomain;
			}
			//设置新节点目标
			if(nextActivityImpl!=null)
				newTransition.setDestination(nextActivityImpl);    				
    		
			
			String signRet =this.saveSignTask(userid, currTask.getProcessInstanceId(), currTask.getId(), signInfo);
			if(signRet!="200"){
				retDomain.setErrorMsg(signRet);
    			return retDomain;
			}
			
			taskService.complete(currTask.getId(), variables);
			
			
			//查找流程实例当前任务节点
			Task task =taskService.createTaskQuery().processInstanceId(currTask.getProcessInstanceId()).singleResult();
			
//			//授权追回节点人员
//			task.setAssignee(assigneeId);
			taskService.saveTask(task);
			
			//恢复方向
			currActivity.getOutgoingTransitions().remove(newTransition);
			currActivity.getOutgoingTransitions().addAll(nextTransitionList);
			
			
			
			retDomain.setSuccessMsg("回退操作成功");
    		return retDomain;   		

    	}
     
     /**
      * 流程节点回退
      * @param domain	流程实体
      * @param backNodeKey	回退节点名称
      * @param userid		操作人员
      * @param signInfo		签收信息
      * @return
      */
     public RetDomain saveSendBack(String userid,BaseFlowDomainInf domain,String backNodeKey,String signInfo) {

    		
    		RetDomain retDomain = new RetDomain();
    		
    		if(domain==null){
    			retDomain.setErrorMsg("流程实例不能为空");
    			return retDomain;
    		}
    		
    		if(domain.getFlowTaskId()==null || domain.getFlowInstId()==null){
    			retDomain.setErrorMsg("流程id不能为空");
    			return retDomain;
    		}
    		
    		    		   		
    		//获取当前节点定义
    		String _key =domain.getTask_def_key();    		
    		
    		    		
    		//跳转节点定义
    		List<ActivityImpl> toActs = NodeUtil.getIncommingNode(domain.getFlowid(),domain.getFlowInstId(),_key, repositoryService, historyService);
    		
    		//判断回退节点是否存在
    		if(toActs==null){
    			retDomain.setErrorMsg("回退节点不存在");
    			return retDomain;
    		}else{
    			if(toActs.size()>1){
    				String _nid = toActs.get(0).getId();
    				
    				//节点是否可执行回退标志
    				boolean canBack = true;
    				
    				//判断多个回退节点是否为相同节点
    				for(int i=1;i<toActs.size();i++){
    					if(_nid.compareTo(toActs.get(i).getId())!=0){
    						canBack = false;
    					}
    				}
    				if(!canBack){
	    				retDomain.setErrorMsg("并行节点无法回退");
	        			return retDomain;
    				}
    			}
    		}    		
    		
			managementService.executeCommand(new JumpCmd(domain.getFlowInstId(),toActs.get(0)));    		
		
			retDomain.setSuccessMsg("回退操作成功");
    		return retDomain;
    		

    	}
     
     private Map<String,String> getNodeUser(Map<String,String> cMap){
    	 
    	 if((cMap ==null) || cMap.isEmpty()){
    		 return null;
    	 }
    	 Map<String,String> userMap = new HashMap<String,String>(); 
    	 
    	 Map<String,String> jobMap = new HashMap<String,String>(); 
    	List<JobRole> jobrole = null;
    	
    	//判断条件是否包含岗位角色代码
  		if(cMap.containsKey("jobcode_in")){
  			
  			//判断条件是否包含部门信息
  			if(cMap.containsKey("deptid")){
  				Object jobcode = cMap.get("jobcode_in");
  				
  				Object deptid = cMap.get("deptid");
  				
  				if(jobcode!=null && deptid!=null){
  					List<VOJobUser> lists =SysConfig.getJobUserByDept(jobcode.toString(), deptid.toString());
  					if(lists!=null){
  						for(VOJobUser vu:lists){
  							jobMap.put(vu.getId().toString(), vu.getId().toString());
  						}
  						userMap = jobMap;
  					}
  					
  				}
  			}else{
	  			jobrole = jobService.getList(cMap,false);
	  			if((jobrole!=null) && (jobrole.size()>0)){
	  				for(JobRole j:jobrole){
	  					jobMap.put(j.getUserid(), j.getUserid());
	  				}
	  				userMap = jobMap;
	  			}
  			}
  		}
  		
  		List<UserRoles> roles = null;
  		if(cMap.containsKey("roleid_in")){
  			roles = roleService.getListAll(cMap);
  			if((roles!=null) && (roles.size()>0)){
  				boolean userEmpty = jobMap.isEmpty();
  				Map<String,String> roleUserMap = new HashMap<String,String>();
				for(UserRoles r:roles){
					String ruid = r.getUserid().toString();
					if(userEmpty)
						roleUserMap.put(ruid, ruid);
					else{
						if(jobMap.containsKey(ruid)){
							roleUserMap.put(ruid, ruid);
						}
					}
				}
				userMap = roleUserMap;
  			}
  		}
  		
  		//人员id条件判断      
  		if(cMap.containsKey("userid_in")){
  			String _uid = cMap.get("userid_in");
  			if(_uid!=null && _uid.trim().length()>0){
  				String[] uarray = _uid.split(",");
  				if(uarray.length>=0){
  					for(String _id:uarray){
  						if(_id!=null &&_id.trim().length()>0){
  							userMap.put(_id, _id);
  						}
  					}
  				}
  			}
  		}
  		
  		//人员id条件判断      
  		if(cMap.containsKey("userid")){
  			String _uid = cMap.get("userid");
  			if(_uid!=null && _uid.trim().length()>0){  				
  				userMap.put(_uid, _uid);  					
  			}
  		}
  		
  		return userMap;
     }
    
    /**
     * 删除工作流
     * @param instId	实例id
     * @param reason	删除原因
     */
    public Boolean deleteProcessInstance(String instId,String reason){
    	
    	if(instId!=null && (instId.trim().length()>0))
    		instId = instId.trim();
    	runtimeService.deleteProcessInstance(instId, reason);
    	
    	return true;    	
    }
    
    

    /**
     * 带缓存的获取流程下一节点
     * @param procInstId
     * @return
     */
   
    public List<String[]> findTaskOutgoing(BaseFlowDomainInf inquiry){
    	
    	List<String[]> _ac = null;
    	if( (inquiry!=null)   &&   (inquiry.getTask_def_key()!=null)  &&   (inquiry.getFlowid()!=null)  ){
    		
    		String _taskKey = inquiry.getTask_def_key();
    		String _activityId = inquiry.getFlowid();
    		
    		//从缓存读取
    		_ac =  SysConfig.getOutgoingMap(_taskKey, _activityId);
    		
    		if(_ac==null || _ac.size()<=0){
    			//缓存中未找到配置，重新查询后台数据库
    			_ac =  findTaskOutgoing(inquiry.getFlowInstId());    			
    			if(_ac!=null && _ac.size()>0){
    				//查询结果不为空，静态缓存数据
    				Map<String,Map<String,List<String[]>>> _tmap=SysConfig.getOutgoingMap();
    				
    				Map<String,List<String[]>> outMaps= 
					_tmap.containsKey(_taskKey)?_tmap.get(_taskKey):new HashMap<String,List<String[]>>();
				
					//添加本节点流向定义
					outMaps .put(_taskKey, _ac);	
					
					//添加本业务模块所有流向定义
					_tmap.put(_activityId, outMaps);
					
					//缓存数据
					SysConfig.setOutgoingMap(_tmap);
    			}
    		}
    		
    		return _ac;
    		
    	}
    	
    	return null;
    	
    }
    /**
     * 获取流程下一节点
     * @param procInstId
     * @return
     */
    @RequestMapping("/findTaskOutgoing.action")
    public List<String[]> findTaskOutgoing(
    		@RequestParam(value="procInstId",required=false)String procInstId){
    	
    	
    	List<String[]> retList = new ArrayList<String[]>();
	  	// 取得流程实例
	  	ProcessInstance instance = runtimeService
                .createProcessInstanceQuery()
                .processInstanceId(procInstId)
                .singleResult();
	  	Task task = taskService.createTaskQuery().processInstanceId(procInstId).singleResult();
    	
		ProcessDefinitionEntity definition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
                .getDeployedProcessDefinition(instance.getProcessDefinitionId());
	  	
		Map<String,String> activityMap = new HashMap<String,String>();
	  	List<ActivityImpl> activitis =((ProcessDefinitionImpl) definition).getActivities();
	  	if(!activitis.isEmpty()){
	  		for(ActivityImpl ac:activitis){
	  			
	  			activityMap.put(ac.getId(), (String) ac.getProperty("name"));
//	  			System.out.println("ActivityImpl Id: " + ac.getId() + " , name:" + ac.getProperty("name")+ " , type:" + ac.getProperty("type") );
	  		}
	  	}
	  	
	 // 取得下一步活动
        ActivityImpl currActivity = ((ProcessDefinitionImpl) definition)
                .findActivity(task.getTaskDefinitionKey());       
        
        List<PvmTransition> transitionList =currActivity.getOutgoingTransitions();   	
        
        if(!transitionList.isEmpty()){
        	for(int i=0;i<transitionList.size();i++){
        		String _id = transitionList.get(i).getDestination().getId();
        		if(activityMap.containsKey(_id)){
        			HashMap<String,String> retMap = new HashMap<String,String>();
        			retMap.put("id",_id);
        			retMap.put("name",activityMap.get(_id));
        			
        			String[] _ac = {_id,activityMap.get(_id)};
        			retList.add(_ac);
        		}
        	}        	
        }
        
        return retList;
	  }
    
    /**
     * 流程实例下一节点人员设置
     * @param procInstId
     * @return
     */
    @SuppressWarnings("unused")
	private void delegateNextNode(String procInstId){
    	
    	
    }
    
    /**
     * 查找下一节点人员信息
     * @param inquiry
     */
    @SuppressWarnings("unchecked")
	public Map<String,String> getNextNodeAssignConditionMap(BaseFlowDomainInf inquiry) {
  		
  		Map<String,String> conditionMap = new HashMap<String,String>();
  		
  		
  		conditionMap.put("procDefinitionId", inquiry.getFlowid());
  		conditionMap.put("fullBizcode", inquiry.getFullBizcode());		  	
	  	
		 //find out going
	  	List<String[]> inmap=	this.findTaskOutgoing(inquiry);
	  	
	  	//用户map
	  	Map<String,String> cMap = new HashMap<String,String>();
	  	
	  	//判断是否结束节点
	  	if(inmap!=null && inmap.size()>0){
		  	String activityid = inmap.get(0)[0];
		  	conditionMap.put("activityId", activityid);
		  	
		  	//find task node config		  	
		  	Map<String,Object> allmaps =SysConfig.getFlowNodeMaps();
		  	
		  	Map<String,Map<String,String>> maps = (Map<String, Map<String, String>>) allmaps.get(activityid+inquiry.getFullBizcode());
		  	//角色、用户过滤
		  	Map<String,String> roleuserMap = null;
		  	//字段定义数据
		  	Map<String,String> fieldMap = null;
		  	//主管、分管领导过滤数据
		  	Map<String,String> leaderMap = null;
		  	if(maps!=null ){
		  		if( maps.containsKey("roleUserFilter")){
		  			roleuserMap = maps.get("roleUserFilter");
			  	}
		  		if( maps.containsKey("fieldFilter")){
		  			fieldMap = maps.get("fieldFilter");
			  	}
		  		if(maps.containsKey("leader")){
		  			leaderMap =maps.get("leader");
		  		}
		  	}
		  	
		  	
		  	//获取字段条件字段值
		  	if(fieldMap!=null && !fieldMap.isEmpty()){
		  		
		  		cMap = MapUtil.getReflectFiedCondition(fieldMap,inquiry, "dept", "deptid",cMap);
		  		
		  		
		  		cMap = MapUtil.getReflectFiedCondition(fieldMap, inquiry,"user", "userid",cMap);
		  			  		
		  	}
		  	
		  //获取人员条件字段值
		  	if(roleuserMap!=null && !roleuserMap.isEmpty()){
		  		cMap = MapUtil.getMapCondition(roleuserMap, "role", "roleid_in",cMap);
		  		
		  		
		  		cMap = MapUtil.getMapCondition(roleuserMap, "job_role", "jobcode_in",cMap);
		  		
		  		
		  		cMap = MapUtil.getMapCondition(roleuserMap, "title_role", "titlecode_in",cMap);
		  		
		  		cMap = MapUtil.getMapCondition(roleuserMap, "user", "userid_in",cMap);		  		
		  	}
		  	
		  	
		  	NodeUser.getInstance();  	
		  	//获取字段条件字段值
		  	cMap = NodeUser.getFieldUser(fieldMap, cMap, inquiry);
		  	
			  	
		    //获取人员条件字段值
		  	cMap = NodeUser.getRoleUser(roleuserMap, cMap, inquiry);
		  	
			  	
		  	//获取主管、分管领导过滤条件
		  	if(leaderMap!=null && !leaderMap.isEmpty()){	
			  	
				//获取主管领导过滤条件
		  		cMap = NodeUser.getLeaderUser(leaderMap, cMap, inquiry);
		  		//业务分管领导过滤条件判断
		  		cMap = NodeUser.getBizLeaderUser(leaderMap, cMap, inquiry);
		  		
		  	}
		  	
//	  	Object obj =ReflectDataUtil.getFieldValue(maps.get("filter"), inquiry);
	  	}
	  	return cMap;
	    
	}
    
    /**
     * 查找当前节点人员信息
     * @param inquiry
     */
    @SuppressWarnings({ "unchecked"})
	public Map<String,String> getCurrentNodeAssignMap(BaseFlowDomainInf inquiry) {
  		
  		Map<String,Object> allmaps =SysConfig.getFlowNodeMaps();
  		Map<String,Map<String,String>> maps = (Map<String, Map<String, String>>) allmaps.get(inquiry.getTask_def_key()+inquiry.getFullBizcode());	 
	  	
	  	//用户map
	  	Map<String,String> cMap = new HashMap<String,String>();  	
	  	
	  	//角色、用户过滤
	  	Map<String,String> roleuserMap = null;
	  	//字段定义数据
	  	Map<String,String> fieldMap = null;
	  	//主管、分管领导过滤数据
	  	Map<String,String> leaderMap = null;
	  	if(maps!=null ){
	  		if( maps.containsKey("roleUserFilter")){
	  			roleuserMap = maps.get("roleUserFilter");
		  	}
	  		if( maps.containsKey("fieldFilter")){
	  			fieldMap = maps.get("fieldFilter");
		  	}
	  		if(maps.containsKey("leader")){
	  			leaderMap =maps.get("leader");
	  		}
	  	}
		  	
	  	NodeUser.getInstance();  	
	  	//获取字段条件字段值
	  	cMap = NodeUser.getFieldUser(fieldMap, cMap, inquiry);
	  	
		  	
	    //获取人员条件字段值
	  	cMap = NodeUser.getRoleUser(roleuserMap, cMap, inquiry);
	  	
		  	
	  	//获取主管、分管领导过滤条件
	  	if(leaderMap!=null && !leaderMap.isEmpty()){	
		  	
			//获取主管领导过滤条件
	  		cMap = NodeUser.getLeaderUser(leaderMap, cMap, inquiry);
	  		//业务分管领导过滤条件判断
	  		cMap = NodeUser.getBizLeaderUser(leaderMap, cMap, inquiry);
	  		
	  	}
	  	
	  	return cMap;
	    
	}
    
    
    /**
     * 流程授权给指定人员
     * @param inquiry
     */
    @RequestMapping("/assignTask.action")
    public RetDomain assignTask(@RequestParam(value="flowInstId",required=false)String flowInstId,
    		@RequestParam(value="userid",required=false)String userid){
    	
    	RetDomain r = RetDomain.successDomain("操作成功");
    	if( (flowInstId !=null)   &&   (userid != null) ){
    		Task t = taskService.createTaskQuery().processInstanceId(flowInstId).singleResult();
    		
    		taskService.addCandidateUser(t.getId(), userid);
    		
    		return r;
    	}
    	
    	return RetDomain.errorDomain("操作失败");
    }
    
    /**
     * 验证当前节点用户是否可以操作流程业务记录
     * @param flowInstId	流程实例id
     * @param userid		用户id
     * @return
     */
    @RequestMapping("/validateFlowUser.action")
    public int validateFlowUser(@RequestParam(value="flowInstId",required=false)String flowInstId,
    		@RequestParam(value="userid",required=false)String userid){
		
    		int ret = 0;
    		if((flowInstId!=null)  && (userid!=null)){
    			List<Task> groupTasks = taskService.createTaskQuery().processInstanceId(flowInstId).taskCandidateUser(userid).list();
    			if(groupTasks.size()==1){
    				ret = 1;
    			}
    		}
    		return ret;
	}
    
    /**
     * 流程业务记录用户授权签收
     * @param flowInstId	流程实例id
     * @param userid		用户id
     * @return
     */
    @RequestMapping("/flowsign.action")
    public int flowsign(@RequestParam(value="flowInstId",required=false)String flowInstId,
    		@RequestParam(value="userid",required=false)String userid){		
    	
    	if(flowInstId !=null && userid!=null){
    		Task task = taskService.createTaskQuery().processInstanceId(flowInstId).singleResult();
    		task.setAssignee(userid);
    		taskService.saveTask(task);		  
    		return 200;
    	}
    	return 400;
	}
    
    /**
     * 流程人员授权
     * @param processInstance	流程实例
     * @param map	流程实例变量，<code>List<String></code> groups, 
     * 				<code>String</code> group, 
     * 				<code>List<String></code> users,
     * 				<code>String</code> user,
     * 				至少提供一个参数，否则task将无法被查询列表显示
     * @return	返回操作执行情况
     */
    @SuppressWarnings("unused")
	private Boolean addCandidate(ProcessInstance processInstance,Map<String,Object> map){
    	
    	
    	Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
    	if((task!=null)&&task.getId()!=null){
    		return this.addCandidate(task, map);
    	}else{
    		return false;
    	}
    }
    
    @SuppressWarnings("unchecked")
	private Boolean addCandidate(Task task,Map<String,Object> map){
    	
    	Boolean isCandidate = null;
	   	if((task!=null)&&task.getId()!=null){
	   	 
		   	//判断是否设置授权组
		    List<String> groups =   (List<String>) map.get("groups");
		    if((groups!=null)&&(!groups.isEmpty())){
		    	for(String groupid:groups)
		    		taskService.addCandidateGroup(task.getId(), groupid);
		    	
		    	isCandidate = true;
		    }
		    
		    String group = (String) map.get("groups");
		    //判断是否设置授权组
		    if((group!=null)&&(group.trim().length()>=0)){
		    	taskService.addCandidateGroup(task.getId(),group);
		    	isCandidate = true;
		    }
		    
		    //判断是否设置授权组
		    List<String> users =   (List<String>) map.get("users");
		    if((users!=null)&&(!users.isEmpty())){
		    	for(String userid:users)
		    		taskService.addCandidateUser(task.getId(),userid);
		    	
		    	isCandidate = true;
		    }
		    
		    String user = (String) map.get("user");
		    //判断是否设置授权组
		    if((user!=null)&&(user.trim().length()>=0)){
		    	taskService.addCandidateUser(task.getId(),user);
		    	isCandidate = true;
		    }        
	        return isCandidate;
        }else{
        	return false;
        }
   }

    

}
